#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>

#include "memdb.h"
#include "filedb.h"

//#define DEBUG_MEMDB

//----------------------------------------------------------------------------
// initialization for in-memory buffers
//----------------------------------------------------------------------------
int init_memdb (cfg_t *cfg)
{
	if (cfg->buf_size <= 0) cfg->buf_size = 10;
	
	cfg->old = malloc (sizeof (buf_t));
	memset (cfg->old, 0, sizeof (buf_t));
	cfg->old->pt = malloc (cfg->buf_size * sizeof (pt_t));
	memset (cfg->old->pt, 0, cfg->buf_size * sizeof (pt_t));

	cfg->new = malloc (sizeof (buf_t));
	memset (cfg->new, 0, sizeof (buf_t));
	cfg->new->pt = malloc (cfg->buf_size * sizeof (pt_t));
	memset (cfg->old->pt, 0, cfg->buf_size * sizeof (pt_t));
	
	return 0;
}

//----------------------------------------------------------------------------
// find first point in in-memory buffers, else return (-1)
//----------------------------------------------------------------------------
int memdb_first_pt (cfg_t *cfg, pt_t *pt)
{
	int ret = -1;
	
	if (cfg->old->npt > 0) {
		*pt = cfg->old->pt [0];
		ret = 0;
	} else 
	if (cfg->new->npt > 0) {
		*pt = cfg->new->pt [0];
		ret = 0;
	} else {
		memset (pt, 0, sizeof (pt_t));
	}
	
	return ret;
}

//----------------------------------------------------------------------------
// build buffer with values from in-memory buffer 
// with [(pre)& (t_beg <= t <= t_end)& (post)]
//----------------------------------------------------------------------------
int query_memdb (cfg_t *cfg, double t_beg, double t_end, pt_t **pt_buf, int *size)
{
	int i, j;
	pt_t *out;
	pt_t *membuf;
	int out_size;
	int membuf_size;
	int end_found;
	
	out = NULL;
	out_size = 0;
	membuf = NULL;
	membuf_size = 0;
	end_found = 0;
	
	for (i= 0; i< 2; i++) {
		switch (i) {
			case 0: 
				membuf = cfg->old->pt;
				membuf_size = cfg->old->npt;
				break;
			case 1:
				membuf = cfg->new->pt;
				membuf_size = cfg->new->npt;
				break;
		}
			
		if (membuf_size > 0) {			
			//printf ("hello %d\n", i);
			if (membuf [membuf_size - 1].t <  t_beg) {
				//printf ("1 - hello %d\n", i);
				out_size = 1;
				out = realloc (out, sizeof (pt_t));
				out [0] = membuf [membuf_size - 1];
			} else if (membuf [0].t < t_beg) {
				//printf ("2 - hello %d\n", i);
				for (j= 0; j< membuf_size; j++) {
					if (membuf [j].t >= t_beg) {
						break;	
					}
				}
				//printf ("j = %d\n", j);
				if (j > 0) {
					out_size += (membuf_size - (j-1));
					out = realloc (out, out_size * sizeof (pt_t));
					memcpy (&out [out_size - (membuf_size - (j-1))], &membuf [j-1], (membuf_size - (j-1)) * sizeof (pt_t));
				} else {
					out_size += (membuf_size - j);
					out = realloc (out, out_size * sizeof (pt_t));
					memcpy (&out [out_size - (membuf_size - j)], &membuf [j], (membuf_size - j) * sizeof (pt_t));
				}					
					
			} else if (membuf [membuf_size - 1].t <= t_end) {
				//printf ("3 - hello %d, membuf_size = %d\n", i, membuf_size);
				out_size += membuf_size;
				out = realloc (out, out_size * sizeof (pt_t));
				memcpy (&out [out_size - membuf_size], membuf, membuf_size * sizeof (pt_t));
					
			} else {
				//printf ("4 - hello %d\n", i);
				for (j= 0; j< membuf_size; j++) {
					if (membuf [j].t > t_end) {
						//printf ("4 - hello %d\n", j);
						end_found = 1;
						break;
					}		
				}
				j++;
				out_size += j;
				out = realloc (out, out_size * sizeof (pt_t));
				memcpy (&out [out_size - j], membuf, j * sizeof (pt_t));
				
			}		
		}		
	}		
	
	*pt_buf = out;
	*size = out_size;
	return end_found;
}
